package com.zt.bus.order.service;

import com.zt.bus.alipay.service.AliPayService;
import com.zt.bus.constant.BusConstant;
import com.zt.bus.line.model.Dispatch;
import com.zt.bus.line.service.DispatchService;
import com.zt.bus.order.inter.OrderDetailMapper;
import com.zt.bus.order.inter.OrderMapper;
import com.zt.bus.order.inter.OrderPaymentMapper;
import com.zt.bus.order.model.Order;
import com.zt.bus.order.model.OrderBack;
import com.zt.bus.order.model.OrderDetail;
import com.zt.bus.order.model.OrderPayment;
import com.zt.bus.sms.service.SendCodeService;
import com.zt.bus.wx.service.WxPayService;
import com.zt.system.model.BusinessException;
import com.zt.system.service.BaseService;
import com.zt.util.DateUtil;
import com.zt.util.PropertiesUtil;
import com.zt.util.StringUtil;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderPaymentService extends BaseService {

    @Autowired
    private OrderPaymentMapper orderPaymentMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderBackService orderBackService;
    @Autowired
    private AliPayService aliPayService;
    @Autowired
    private OrderStatusCheckService orderStatusCheckService;
    @Autowired
	private SendCodeService sendCodeService;
    @Autowired
    private DispatchService dispatchService;
    // 方案调度短信模板id
 	public static final String PLAN_ALLOCATION = PropertiesUtil.getProperty("plan_allocation");
 	
    public OrderPayment getByOrderId(String orderId) {
        return orderPaymentMapper.selectByOrderId(orderId);
    }

    public OrderPayment getByPrimaryKey(String tradeNo) {
        return orderPaymentMapper.selectByPrimaryKey(tradeNo);
    }

    public void updateOrderPayment(OrderPayment orderPayment) {
        if (orderPayment == null) {
            throw new BusinessException("订单信息不存在");
        }
        orderPaymentMapper.updateByPrimaryKeySelective(orderPayment);
    }

    /**
     * 提交给支付平台前，生成支付信息 下单前拼凑支付信息
     * 
     * @param payPlatform
     * @param orderId
     * @param bookUserPhone
     * @return
     */
    public OrderPayment getOrderPayment(String payPlatform, String orderId, String bookUserPhone) {
        if (StringUtil.isEmpty(orderId) || StringUtil.isEmpty(bookUserPhone) || StringUtil.isEmpty(payPlatform)) {
            throw new BusinessException("创建订单支付记录，缺少参数！");
        }
        // 校验支付平台
        checkPayPlatform(payPlatform);

        Order order = orderService.getById(orderId);
        if (order == null || !order.getBookUserPhone().equals(bookUserPhone)) {
            throw new BusinessException("订单未保存！");
        }
        // 校验订单状态
        checkToBePaidOrderStatus(order.getStatus());

        OrderPayment payment = new OrderPayment();
        Date orderDate = new Date();
        payment.setTradeNo("DZ" + payPlatform + orderDate.getTime() + orderId);
        payment.setOrderId(orderId);
        payment.setBookUserPhone(bookUserPhone);
        payment.setCashAmount(order.getCashAmount());
        payment.setPayPlatform(payPlatform);
        payment.setPayType(BusConstant.PaymentType.BOOK);
        payment.setOrderTime(orderDate);

        return payment;
    }

    /**
     * 与支付平台下单之后创建支付记录 支付返回交易号设置交易号
     * 
     * @param payment
     */
    public void createOrderPayment(OrderPayment payment) {
        if (payment == null || StringUtil.isEmpty(payment.getTradeNo()) || StringUtil.isEmpty(payment.getOrderId())
                || StringUtil.isEmpty(payment.getBookUserPhone()) || payment.getOrderTime() == null
                || payment.getCashAmount() == 0) {
            throw new BusinessException("支付下单，缺少参数！");
        }
        if (!BusConstant.PaymentType.BOOK.equals(payment.getPayType())
                && !BusConstant.PaymentType.BACK.equals(payment.getPayType())) {
            throw new BusinessException("支付类型失败！");
        }
        // 校验支付平台
        checkPayPlatform(payment.getPayPlatform());

        if (BusConstant.PaymentType.BACK.equals(payment.getPayType())) {// 退订

            OrderBack orderBack = orderBackService.getById(payment.getOrderId());

            payment.setCashAmount(payment.getCashAmount());
        } else {
            Order order = orderService.getById(payment.getOrderId());
            if (order == null || !order.getBookUserPhone().equals(payment.getBookUserPhone())) {
                throw new BusinessException("订单不存在！");
            }
            // 校验订单状态
            checkToBePaidOrderStatus(order.getStatus());

            payment.setCashAmount(order.getCashAmount());
        }
        payment.setPayTime(new Date());
        payment.setPayStatus(BusConstant.PaymentStatus.TO_BE_PAID);// 这里还是待支付状态
        orderPaymentMapper.insert(payment);
    }

    /**
     * 用户完成支付动作 js确定回调
     * 
     * @param tradeNo
     */
    public void paymentCompleted(String tradeNo) {
        if (StringUtil.isEmpty(tradeNo)) {
            throw new BusinessException("完成支付，缺少参数！");
        }
        OrderPayment payment = orderPaymentMapper.selectByPrimaryKey(tradeNo);
        if (payment == null) {
            throw new BusinessException("支付订单不存在！");
        }

        // 订单已回调确认成功
        if (BusConstant.PaymentStatus.PAYMENT_SUCCESSFUL.equals(payment.getPayStatus())
                || BusConstant.PaymentStatus.PAYMENT_FAILED.equals(payment.getPayStatus())) {
            return;
        }
        if (!BusConstant.PaymentStatus.TO_BE_PAID.equals(payment.getPayStatus())) {
            throw new BusinessException("支付订单状态异常！");
        }
        payment.setPayStatus(BusConstant.PaymentStatus.TO_BE_CONFIRMED);
        orderPaymentMapper.updateByPrimaryKey(payment);

        // 修改订单状态
        Order order = orderService.getById(payment.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在！");
        }
        if (!BusConstant.OrderStatus.TO_BE_PAID.equals(order.getStatus())) {
            throw new BusinessException("支付订单状态异常！");
        }
        order.setStatus(BusConstant.OrderStatus.TO_BE_CONFIRMED);
        orderService.updatePayStatus(order);
        orderStatusCheckService.hasPaid(order);// 更改状态检查
    }

    /**
     * 用户取消支付
     * 
     * @param tradeNo
     */
    public void paymentCanceled(String tradeNo) {
        if (StringUtil.isEmpty(tradeNo)) {
            throw new BusinessException("取消支付，缺少参数！");
        }
        OrderPayment payment = orderPaymentMapper.selectByPrimaryKey(tradeNo);
        if (payment == null) {
            throw new BusinessException("支付订单不存在！");
        }
        if (!BusConstant.PaymentStatus.TO_BE_PAID.equals(payment.getPayStatus())
                && !BusConstant.PaymentStatus.PAYMENT_CANCEL.equals(payment.getPayStatus())) {
            throw new BusinessException("支付订单状态异常！");
        }
        payment.setPayStatus(BusConstant.PaymentStatus.PAYMENT_CANCEL);
        orderPaymentMapper.updateByPrimaryKey(payment);

        // 修改订单状态
        Order order = orderService.getById(payment.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在！");
        }
        if (!BusConstant.OrderStatus.TO_BE_PAID.equals(order.getStatus())
                && !BusConstant.OrderStatus.PAYMENT_CANCEL.equals(order.getStatus())) {
            throw new BusinessException("支付订单状态异常！");
        }
        order.setStatus(BusConstant.OrderStatus.PAYMENT_CANCEL);
        orderService.updatePayStatus(order);
        orderStatusCheckService.cancelOrder(order);// 更改状态检查
    }

    /**
     * 设置支付结果 notify_url中正确回调处理
     * 
     * @param tradeNo
     * @param isSuccess
     * @param resultMsg
     */
    public void paymentSetResult(String tradeNo, String payPlatformNo, boolean isSuccess, String resultMsg) {
        if (StringUtil.isEmpty(tradeNo)) {
            throw new BusinessException("取消支付，缺少参数！");
        }
        OrderPayment payment = orderPaymentMapper.selectByPrimaryKey(tradeNo);
        if (payment == null) {
            throw new BusinessException("支付订单不存在！");
        }
        // 微信支付订单号
        payment.setPayPlatformNo(payPlatformNo);
        // if
        // (!BusConstant.PaymentStatus.TO_BE_CONFIRMED.equals(payment.getPayStatus()))
        // {
        // throw new BusinessException("支付订单状态异常！");
        // }
        payment.setPayStatus(isSuccess ? BusConstant.PaymentStatus.PAYMENT_SUCCESSFUL
                : BusConstant.PaymentStatus.PAYMENT_FAILED);
        payment.setResultMsg(resultMsg);
        payment.setResultTime(new Date());
        orderPaymentMapper.updateByPrimaryKey(payment);

        // 修改订单状态
        Order order = orderService.getById(payment.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在！");
        }
        // 不是待支付或者待确认的话，抛异常
        if (!BusConstant.OrderStatus.TO_BE_CONFIRMED.equals(order.getStatus()) //待支付
                && !BusConstant.OrderStatus.TO_BE_PAID.equals(order.getStatus()) //待确认
                && !BusConstant.OrderStatus.PAYMENT_CANCEL.equals(order.getStatus()) //支付取消
                && !BusConstant.OrderStatus.PAYMENT_FAILED.equals(order.getStatus()) //支付失败
                && !BusConstant.OrderStatus.PAYMENT_SUCCESSFUL.equals(order.getStatus())) {
            throw new BusinessException("支付订单状态异常！");
        }
        order.setStatus(isSuccess ? BusConstant.OrderStatus.PAYMENT_SUCCESSFUL : BusConstant.OrderStatus.PAYMENT_FAILED);
		if (isSuccess) {
			orderStatusCheckService.hasPaid(order);// 更改状态检查

			// 对于预定了已分配司机车辆的方案要给用户进行短信提示
			
			List<OrderDetail> orderDetailList = orderDetailMapper.selectByOrderId(order.getId());// 该订单的订单明细
			String driverInfo = "";// 司机信息
			String vehicleInfo = "";// 车辆信息
			Map<Date, String> map = new HashMap<Date, String>();
			for (OrderDetail orderDetail : orderDetailList) {
				if (!map.containsKey(orderDetail.getRideDate())) {// 该日期没有发过短信
					map.put(orderDetail.getRideDate(), "该日期已发送短信");
					List<Dispatch> dispatchList = dispatchService.getByPlanIdAndDepartDate(order.getPlanId(),
							orderDetail.getRideDate());
					if (dispatchList == null || dispatchList.size() == 0) {// 该日期还未分配司机车辆
						continue;
					}
					for (Dispatch dispatch : dispatchList) {
						driverInfo += dispatch.getDriverName() + "(" + dispatch.getDriverPhone() + ")" + "、";
						vehicleInfo += dispatch.getVehicleNo() + "、";
					}
					driverInfo = driverInfo.substring(0, driverInfo.length() - 1);
					vehicleInfo = vehicleInfo.substring(0, vehicleInfo.length() - 1);

					// 短信内容
					String info = order.getLineName() + "线路(订单号:"+order.getId()+")已分配司机和车辆(司机:" + driverInfo + ";车辆:" + vehicleInfo + ")";
					JSONObject json = new JSONObject();
					json.put("msgInfo", info);
					json.put("departTime",DateUtil.formatDate(orderDetail.getRideDate()) + " " + order.getDepartTime());
					String bookUserPhone = order.getBookUserPhone();
					sendCodeService.sendSms(order.getId(), bookUserPhone, json.toString(), "方案调度短信提醒", PLAN_ALLOCATION);
				}
			}
		}

        //修改订单以及订单明细状态
        orderMapper.updateByPrimaryKeySelective(order);
        // 修改订单明细表状态
        List<OrderDetail> details = orderDetailMapper.selectByOrderId(order.getId());
        for (OrderDetail detail : details) {
            //只更新订单明细状态为待支付的订单明细
            if(BusConstant.PaymentStatus.TO_BE_PAID.equals(detail.getStatus())) {
                if (!order.getStatus().equals(detail.getStatus())) {
                    detail.setStatus(order.getStatus());
                    orderDetailMapper.updateByPrimaryKey(detail);
                }
            }
        }
    }

    /**
     * 退款
     * 
     * @param orderBack
     */
    public OrderPayment createOrderBackPayment(OrderBack orderBack) {
        Date date = new Date();
        // 获取退款金额
        double refundFee = orderBack.getRefundFee();// 手续费
        double refundAmount = orderBack.getRefundAmount();// 订单退款金额
        String orderId = orderBack.getOrderId();
        // 获取 订单信息 支付成功的订单
        OrderPayment orderPayment = getByOrderId(orderId);
        double cashAmount = orderPayment.getCashAmount();// 订单总金额
        double refundMoney = refundAmount - refundFee;// 实际应退金额

        // 生成支付的订单(退订)
        OrderPayment payment = new OrderPayment();
        payment.setTradeNo("TD" + orderPayment.getPayPlatform() + date.getTime() + orderBack.getOrderBackId());
        payment.setPayPlatformNo(orderPayment.getPayPlatformNo());
        payment.setOrderId(orderBack.getOrderBackId());
        payment.setPayType(BusConstant.PaymentType.BACK); // 支付类型
        payment.setPayStatus(BusConstant.PaymentStatus.TO_BE_PAID);// 支付状态
        payment.setCashAmount(refundMoney);
        payment.setBookUserPhone(orderPayment.getBookUserPhone());
        payment.setPayPlatform(orderPayment.getPayPlatform());
        payment.setOrderTime(date); // 生成时间
        createOrderPayment(payment);
        // todo 调退款接口 根据支付类型区分，调不同的支付接口
        //微信公众号退款或者微信app退款
        if (BusConstant.PayPlatform.WEIXIN_WEB.equals(orderPayment.getPayPlatform())
                || BusConstant.PayPlatform.WEIXIN_APP.equals(orderPayment.getPayPlatform())) {
        	orderPayment = wxPayService.orderPayRefund(payment.getTradeNo(), orderPayment.getPayPlatformNo(),orderPayment.getPayPlatform(),
                    String.valueOf(cashAmount * 100), String.valueOf(refundMoney * 100));
        } else if(BusConstant.PayPlatform.ALIPAY_APP.equals(orderPayment.getPayPlatform())) {
            //支付宝app退款
            orderPayment = aliPayService.orderPayRefund(payment.getTradeNo(), orderPayment.getPayPlatformNo(),
                    String.valueOf(cashAmount * 100), String.valueOf(refundMoney * 100));
        } else if(BusConstant.PayPlatform.ALIPAY_WEB.equals(orderPayment.getPayPlatform())) {
            //支付宝wap退款
            orderPayment = aliPayService.orderPayRefund(payment.getTradeNo(), orderPayment.getPayPlatformNo(),
                    String.valueOf(cashAmount * 100), String.valueOf(refundMoney * 100));
        }
        return orderPayment;
    }

    /**
     * 校验支付平台
     * 
     * @param payPlatform
     */
    public void checkPayPlatform(String payPlatform) {
        if (!BusConstant.PayPlatform.UNIONPAY_WEB.equals(payPlatform)
                && !BusConstant.PayPlatform.UNIONPAY_APP.equals(payPlatform)
                && !BusConstant.PayPlatform.ALIPAY_WEB.equals(payPlatform)
                && !BusConstant.PayPlatform.ALIPAY_APP.equals(payPlatform)
                && !BusConstant.PayPlatform.WEIXIN_WEB.equals(payPlatform)
                && !BusConstant.PayPlatform.WEIXIN_APP.equals(payPlatform)) {
            throw new BusinessException("未知支付方式！");
        }
    }

    /**
     * 校验待支付订单的状态
     * 
     * @param status
     */
    public void checkToBePaidOrderStatus(String status) {
        if (BusConstant.OrderStatus.TO_BE_CONFIRMED.equals(status)) {
            throw new BusinessException("订单正在支付中，请确认支付结果！");
        }
        if (BusConstant.OrderStatus.PAYMENT_SUCCESSFUL.equals(status)) {
            throw new BusinessException("订单已支付成功，请勿重复支付！");
        }
        if (BusConstant.OrderStatus.TIMEOUT_OFF.equals(status) || BusConstant.OrderStatus.CLOSED.equals(status)) {
            throw new BusinessException("订单已关闭，请重新下单！");
        }
    }

}
